home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / quintus / quintus0.lha / work / library_2.06.2 < prev    next >
Text File  |  1992-04-03  |  23KB  |  905 lines

  1. %%% LIBRARY SECTION
  2. %%% version 2.00.0 (based on library_16.3)
  3. %%%   added identical_delete_all
  4. %%%   added identical_delete_all_duplicates
  5. %%% version 2.00.1
  6. %%%   added var_eq_member
  7. %%%   added var_eq
  8. %%% version 2.00.5
  9. %%%   added list_vars
  10. %%% version 2.00.9
  11. %%%   added count_occurrences
  12. %%%   fixed bug in var_eq
  13. %%%   moved ground from rewrite to library
  14. %%%   moved unground from rewrite to library
  15. %%%   added increment_counter
  16. %%%   added set_counter
  17. %%%   optimized var_eq
  18. %%% version 2.01.9
  19. %%%   optimized term rewriting
  20. %%% version 2.04.0
  21. %%%   logically erased nuclei while hyper-linking
  22. %%% version 2.04.3
  23. %%%   added reverse/2
  24. %%% version 2.04.6
  25. %%%   added min_list
  26. %%%   added get_list
  27. %%% version 2.04.8
  28. %%%   added get_subterms
  29. %%% version 2.05.1
  30. %%%   added gensym
  31. %%%   added common_variables
  32. %%% version 2.05.3
  33. %%%   moved numbervars to als
  34. %%%   replaced integer_name with name
  35. %%% version 2.05.8
  36. %%%   removed append/3
  37. %%% version 2.06.0
  38. %%%   added is_subterm/2
  39. %%%   added identical_subset/2
  40. %%%   added identical_set_difference/3
  41. %%%   added substitute_term/4
  42. %%%   added identical_embedded/2
  43. %%%   added identical_set/2
  44. %%%   made delete_all/3 and identical_delete_all/3 deterministic
  45. %%%   added replace_list/4
  46. %%%   or_list/2
  47. %%% version 2.06.1
  48. %%%   added substitute_term_all/4
  49. %%%   added permutations/2
  50. %%%   added append_lists/2
  51. %%%   added tail/2
  52. %%%   added retract_all/1
  53. %%% version 2.06.2
  54. %%%   added ground_like/4
  55. %%%   added term_size_structure/2
  56. %%%   added enumerate/4
  57.  
  58. %%%
  59. %%% LINEARIZATION
  60. %%%
  61. %%% linearize_term creates a linearized version of a term i.e.
  62. %%% linearize_term(p(X,X),p(X,V),[X],[V])
  63. %%% call at top level by linearize_term(Term,X,Y,Z).
  64. %%% To make possible fast unification
  65. %%% using Prolog's built in unification without occurs check.
  66.  
  67.      linearize_term(Term, Term, [], []) :-
  68.     numbervars(Term,0,0), !.
  69.      linearize_term(Term, Newterm, Vars1, Vars2) :-
  70.     linearize(Term, Newterm, [], [], Oldvars, Newvars),
  71.     pairs(Oldvars, Newvars, Vars1, Vars2, Vars3), !.    
  72.  
  73. %%% Makes use of predicate linearize, with arguments as follows:
  74. %%% linearize(Input_term, Linearized_version, Previous_oldvars,
  75. %%%    Previous_linearized_vars, New_oldvars, New_linearized_vars)
  76. %%% so linearize(p(X,X),p(U,V),[],[],[X,X],[U,V])
  77. %%% call at top level by linearize(Input_term, Y, [], [], U, V).
  78. %%% generate a new variable S after the first time a
  79. %%% variable is seen.
  80.      linearize(R,S,O1,O2,[R|O1],[S|O2]) :- 
  81.     var(R), identical_member(R,O1), !.
  82. %%% don't generate a new variable S.
  83.      linearize(R,R,O1,O2,[R|O1],[R|O2]) :- var(R), !.
  84.      linearize(R,S,Old1,Old2,New1,New2) :-
  85.     R =.. [F|Rlist],
  86.     linearize2(Rlist,Slist,Old1,Old2,New1,New2),
  87.     S =.. [F|Slist].
  88.  
  89.      linearize2([],[],Old1,Old2,Old1,Old2) :- !.
  90.      linearize2([R|Rlist],[S|Slist],Old1,Old2,New1,New2) :-
  91.     linearize(R,S,Old1,Old2,Mid1,Mid2),!,
  92.     linearize2(Rlist,Slist,Mid1,Mid2,New1,New2).
  93.  
  94. %%% pairs takes two lists and finds matching variables.  For
  95. %%% example, pairs([X,X,Y],[X1,X2,X3],[X1],[X2],[X]).  This
  96. %%% makes use of the lists returned by linearize.
  97.      pairs([X|L1],[Y|L2],[Y|Z1],[W|Z2],V) :- 
  98.     identical_member(X,L1), !,
  99.     firstmatch(X,L1,L2,W),
  100.     pairs(L1,L2,Z1,Z2,Z3),
  101.     remove_duplicates([X|Z3],V).
  102.  
  103.      pairs([X|L1],[Y|L2],Z1,Z2,Z3) :- 
  104.     pairs(L1,L2,Z1,Z2,Z3).
  105.      pairs([],[],[],[],[]).
  106.  
  107.      firstmatch(X,[Y|L1],[Z|L2],Z) :- 
  108.     X==Y,!.
  109.      firstmatch(X,[Y|L1],[Z|L2],W) :-
  110.     firstmatch(X,L1,L2,W).
  111.  
  112. %%% rename a variable if an identical one exists.
  113.      remove_duplicates([X|Y],[U|Y]) :-  
  114.     identical_member(X,Y), !.            
  115.      remove_duplicates(X,X).
  116.  
  117. %%% unify two lists.
  118.      unify_lists([], []) :- !.        
  119.      unify_lists([X|XRest], [Y|YRest]) :-
  120.     unify(X, Y), !,
  121.     unify_lists(XRest, YRest).
  122.  
  123. %%% Occurs check.
  124.      occurs_check(Term, Var) :-
  125.     var(Term), !, Term \== Var.
  126.      occurs_check(Term, Var) :-
  127.     functor(Term, _, Arity),
  128.     occurs_check(Arity, Term, Var).
  129.  
  130.      occurs_check(0, _, _) :- !.
  131.      occurs_check(N, Term, Var) :-
  132.     arg(N, Term, Arg),
  133.     occurs_check(Arg, Var),
  134.     M is N-1, !,
  135.     occurs_check(M, Term, Var).
  136.  
  137. %%% unify with occurs check. 
  138.      unify(X,Y) :- X == Y, !.
  139.      unify(X,Y) :- unify1(X,Y), !.
  140.  
  141.      unify1(X, Y) :-            
  142.     var(X), var(Y), !, X = Y.    
  143.      unify1(X, Y) :- 
  144.     var(X), !, occurs_check(Y, X), X = Y.
  145.      unify1(X, Y) :- 
  146.     var(Y), !, occurs_check(X, Y), Y = X.
  147.      unify1(X, Y) :- 
  148.     atomic(X), !, X = Y.
  149.      unify1(X, Y) :-
  150.     functor(X, F, N), functor(Y, F, N),
  151.     unify1(N, X, Y).
  152.  
  153.      unify1(0, X, Y) :- !.
  154.      unify1(N, X, Y) :- 
  155.     arg(N, X, Xn), arg(N, Y, Yn),
  156.     unify(Xn, Yn),
  157.     M is N-1, !,
  158.     unify1(M, X, Y).
  159.  
  160.  
  161. %%% separate Nth element and the rest from a list.
  162.      retrieve_N(L,NN,X,Rest) :-        
  163.     retrieve_N(L,1,NN,X,Rest), !.
  164.      retrieve_N([L|Ls],N1,N2,X,[L|Rs]) :-
  165.     N1 < N2,
  166.     NN is N1 + 1,
  167.     !,
  168.     retrieve_N(Ls,NN,N2,X,Rs).
  169.      retrieve_N([L|Ls],N,N,L,Ls).
  170.  
  171. %%% separate Nth element and the rest from two lists.
  172.      retrieve_N2(L1,L2,NN,X,Xs,Y,Ys) :-
  173.     retrieve_N2(L1,L2,1,NN,X,Xs,Y,Ys), !.
  174.      retrieve_N2([L1|Ls1],[L2|Ls2],N1,N2,X,[L1|Xs],Y,[L2|Ys]) :-
  175.     N1 < N2,
  176.     NN is N1 + 1,
  177.     !,
  178.     retrieve_N2(Ls1,Ls2,NN,N2,X,Xs,Y,Ys).
  179.      retrieve_N2([L1|Ls1],[L2|Ls2],N,N,L1,Ls1,L2,Ls2).
  180.  
  181. %%% find a member.
  182.      member(X,[X|_]).            
  183.      member(X,[_|Ys]) :- member(X,Ys).
  184.  
  185. %%% find an identical member.
  186.      identical_member(X,[Y|Z]) :- X == Y,!.
  187.      identical_member(X,[Y|Z]) :- identical_member(X,Z).
  188.  
  189. %%% find a member and the rest.
  190.      member_N([X|Xs],X,Xs).        
  191.      member_N([X|Xs],Y,[X|Zs]) :-
  192.     member_N(Xs,Y,Zs).
  193.  
  194. %%% reverse a list.
  195.      reverse(X,Y) :- reverse(X,[],Y).
  196.      reverse([],X,X) :- !.
  197.      reverse([X|Xs],Y,Z) :- reverse(Xs,[X|Y],Z).
  198.  
  199. %%% delete all the occurrences in a list.
  200.      delete_all(_,[],[]) :- !.
  201.      delete_all(X,[X|Ys],Z) :-         
  202.     !,
  203.     delete_all(X,Ys,Z).
  204.      delete_all(X,[Y|Ys],[Y|Z]) :-
  205.     delete_all(X,Ys,Z).
  206.  
  207. %%% delete all the identical occurrences in a list.
  208.      identical_delete_all(_,[],[]) :- !.
  209.      identical_delete_all(X,[Y|Ys],Z) :-
  210.     X==Y,
  211.     !,
  212.     identical_delete_all(X,Ys,Z).
  213.      identical_delete_all(X,[Y|Ys],[Y|Z]) :-
  214.     identical_delete_all(X,Ys,Z).
  215.  
  216. %%% merge with duplicate deletion.
  217.      merge([X|Xs],Y,Z) :-
  218.     member(X,Y),
  219.     !,
  220.     merge(Xs,Y,Z).
  221.      merge([X|Xs],Y,[X|Zs]) :-
  222.     !,
  223.     merge(Xs,Y,Zs).
  224.      merge([],Z,Z).
  225.  
  226. %%% merge of two ordered lists with duplicate deletion.
  227.      ordered_merge([X|XR],[X|YR],[X|Z]) :-
  228.     !,
  229.     ordered_merge(XR,YR,Z).
  230.      ordered_merge([X|XR],[Y|YR],[X|Z]) :-
  231.     X < Y,
  232.     !,
  233.     ordered_merge(XR,[Y|YR],Z).
  234.      ordered_merge([X|XR],[Y|YR],[Y|Z]) :-
  235.     !,
  236.     ordered_merge([X|XR],YR,Z).
  237.      ordered_merge([],Y,Y) :- !.
  238.      ordered_merge(X,[],X).
  239.  
  240. %%% get the minumum of two values.
  241.      minimum(X,Y,Y) :- Y =< X, !.    % red cut.
  242.      minimum(X,Y,X).
  243.  
  244. %%% get the maximum of two values.
  245.      maximum(X,Y,Y) :- Y >= X, !.    % red cut.
  246.      maximum(X,Y,X).
  247.  
  248. %%% calculate the size of a term.
  249. %%% constants: counted as 1.
  250. %%% varaibles: counted as 1.
  251. %%% functiors: counted as 1 plus the size of all its arguments.
  252. %%% predicates: counted as 1 plus the size of all its arguments.
  253.      term_size(Term,Size) :-        
  254.     term_size(Term,0,Size), !.
  255.      term_size(Term,Size1,Size2) :-
  256.     atomic(Term), !, Size2 is Size1 + 1.
  257.      term_size(Term,Size1,Size2) :-
  258.     var(Term), !, Size2 is Size1 + 1.
  259.      term_size(Term,Size1,Size2) :-
  260.     functor(Term,F,N),
  261.     SizeM is Size1 + 1,
  262.     args_size(Term,0,N,SizeM,Size2).
  263.  
  264.      args_size(Term,N1,N2,SizeI,SizeO) :-
  265.     NN is N1 + 1,
  266.     NN =< N2,
  267.     arg(NN,Term,Arg),
  268.     term_size(Arg,SizeI,SizeM),
  269.     !,
  270.     args_size(Term,NN,N2,SizeM,SizeO).
  271.      args_size(Term,N,N,SizeO,SizeO).
  272.  
  273. %%% term_depth is to calculate the number of nesting levels of a term.
  274. %%% constants: counted as 0.
  275. %%% variables: counted as 0.
  276. %%% functors: counted as 1 plus the maximum depth of its arguments.
  277. %%% predicates: counted as 1 plus the maximum depth of its arguments.
  278.      term_depth(X,0) :- var(X), !.
  279.      term_depth(X,0) :- atomic(X), !.
  280.      term_depth(X,D) :-
  281.     X =.. [F|Args],
  282.     arg_depth(Args,0,Darg),
  283.     D is Darg + 1, !.
  284.      arg_depth([A1|As],Din,Dout) :-
  285.     term_depth(A1,D1),
  286.     maximum(Din,D1,D2), !,
  287.     arg_depth(As,D2,Dout).
  288.      arg_depth([],D,D).
  289.  
  290.  
  291. %%% Find the biggest number in a list.
  292. %%% max_list fails if the list is empty.
  293.      max_list([P|Ps],M) :- max_list(Ps,P,M), !.
  294.      max_list([P2|Ps],P1,M) :-
  295.     P2 > P1, !,
  296.     max_list(Ps,P2,M).
  297.      max_list([_|Ps],P1,M) :-
  298.     !, max_list(Ps,P1,M).
  299.      max_list([],M,M).
  300.  
  301. %%% Find the smallest number in a list.
  302. %%% min_list fails if the list is empty.
  303.      min_list([P|Ps],M) :- min_list(Ps,P,M), !.
  304.      min_list([P2|Ps],P1,M) :-
  305.     P2 < P1, !,
  306.     min_list(Ps,P2,M).
  307.      min_list([_|Ps],P1,M) :-
  308.     !, min_list(Ps,P1,M).
  309.      min_list([],M,M).
  310.  
  311. %%% Compute distinct variable list of a term with a left-over dummy variable.
  312. %%%     The left-over dummy variable is used to unify with unequally long
  313. %%%    conatant list.
  314. %%% For example, the list for g(X,f(a,Y)) is [X,Y|Z].
  315.  
  316.      vars_tail(Term,Vars) :-
  317.     vars_tail(Term,[],_,Vars,Hole), !.
  318.  
  319.      vars_tail(Term, Sofar_in, Sofar_in,Hole,Hole) :- atomic(Term), !.
  320.      vars_tail(Term, Sofar_in, Sofar_in,Hole,Hole) :- var(Term),
  321.          identical_member(Term, Sofar_in), !.
  322.      vars_tail(Term, Sofar_in, [Term|Sofar_in],[Term|Hole],Hole) :-
  323.       var(Term), !.
  324.      vars_tail(Term, Sofar_in,Sofar_out,Vars,Hole) :-
  325.     functor(Term, _, N),
  326.     vars_tail(0,N,Term,Sofar_in,Sofar_out,Vars,Hole).
  327.  
  328.      vars_tail(N,N,_,S,S,Hole,Hole) :- !.
  329.      vars_tail(N1,N2,Term,Sofar_in,Sofar_out,Vars,Hole) :-
  330.     M is N1+1,
  331.     arg(M,Term,Arg),
  332.     vars_tail(Arg,Sofar_in,Sofar_mid,Vars,Hole1),
  333.     !,
  334.     vars_tail(M,N2,Term,Sofar_mid,Sofar_out,Hole1,Hole).
  335.  
  336.  
  337. %%% copy a term without using assert and retract.
  338.      new_copy(R,S) :- new_copy(R,S,[],O).
  339.  
  340.      new_copy(R,R,O1,O1) :-
  341.     atomic(R), !.
  342.      new_copy(R,S,O1,O1) :-
  343.     var(R), memcopy(R,O1,S), !.
  344.      new_copy(R,S,O1,[vp(R,S)|O1]) :-
  345.     var(R), !.
  346.      new_copy(R,S,O1,O2) :-
  347.     R =.. [F|Rlist],
  348.     new_copy2(Rlist,Slist,O1,O2),
  349.     S =.. [F|Slist].
  350.  
  351.      new_copy2([],[],O1,O1) :- !.
  352.      new_copy2([R|Rlist],[S|Slist],O1,O2) :-
  353.     new_copy(R,S,O1,M1), !,
  354.     new_copy2(Rlist,Slist,M1,O2).
  355.  
  356.      memcopy(R,[vp(S,T)|_],T) :- R == S, !.
  357.      memcopy(R,[_|Ys],T) :- memcopy(R,Ys,T).
  358.  
  359.  
  360. %%% remove ``not'' if there, add if not.
  361.      negate(not(X),X) :- !.           
  362.      negate(X,not(X)).          
  363.  
  364. %%% return [] if bagof fails.
  365.      bagof1(X,G,C) :-            
  366.     bagof(X,G,C), !.
  367.      bagof1(_,_,[]).
  368.  
  369. %%% check if a term is a list.
  370.      is_list([_|_]) :- !.
  371.      is_list([]).
  372.  
  373. %%% remove all duplicates in a list.
  374.      delete_all_duplicates([X|Xs],[X|Ys]) :-
  375.     delete_all(X,Xs,Z),
  376.     !,
  377.     delete_all_duplicates(Z,Ys).
  378.      delete_all_duplicates([],[]).
  379.  
  380. %%% remove all identical duplicates in a list.
  381.      identical_delete_all_duplicates([X|Xs],[X|Ys]) :-
  382.     identical_delete_all(X,Xs,Z),
  383.     !,
  384.     identical_delete_all_duplicates(Z,Ys).
  385.      identical_delete_all_duplicates([],[]).
  386.  
  387. %%% Make an ordinal list for a list. If a list has N members, then the
  388. %%% ordinal list is [1,...,N].
  389.      corresp_ordinals_list(List,OrdList) :-
  390.     corresp_ordinals_list(List,1,OrdList), !.
  391.      corresp_ordinals_list([_|Ls],N1,[N1|Os]) :-
  392.     N2 is N1 + 1, !,
  393.     corresp_ordinals_list(Ls,N2,Os).
  394.      corresp_ordinals_list([],_,[]).
  395.  
  396. %%% The list contains of |C| L2's, and one L1's at Nth position.
  397.      list_one_N(C,L2,N,L1,List) :-
  398.     list_one_N(C,L2,1,N,L1,List), !.
  399.      list_one_N([_|Lits],L2,N2,N2,L1,[L1|List]) :-
  400.     NN is N2 + 1,
  401.     !, list_one_N(Lits,L2,NN,N2,L1,List).
  402.      list_one_N([_|Lits],L2,N1,N2,L1,[L2|List]) :-
  403.     NN is N1 + 1,
  404.     !, list_one_N(Lits,L2,NN,N2,L1,List).
  405.      list_one_N([],_,_,_,_,[]).
  406.  
  407. %%% The output contains of |C| binary numbers, and the content in positions
  408. %%%    specified by the list L are N2, the others are N1.
  409.      list_multi_Ns(C,N1,L,N2,List) :-
  410.     list_multi_Ns(C,N1,1,L,N2,List), !.
  411.      list_multi_Ns([_|Lits],N1,N,[N|L],N2,[N2|List]) :-
  412.     NN is N + 1,
  413.     !, list_multi_Ns(Lits,N1,NN,L,N2,List).
  414.      list_multi_Ns([_|Lits],N1,N,L,N2,[N1|List]) :-
  415.     NN is N + 1,
  416.     !, list_multi_Ns(Lits,N1,NN,L,N2,List).
  417.      list_multi_Ns([],_,_,_,_,[]).
  418.  
  419. %%% The list contains of |C| L2's.
  420.      list_of_Ns([_|Lits],L2,[L2|List]) :-
  421.     !, list_of_Ns(Lits,L2,List).
  422.      list_of_Ns([],_,[]).
  423.  
  424. %%% A list of natural numbers from 1 to N.
  425.      list_of_natural_numbers_up_to_N(N,Un) :-
  426.     list_of_natural_numbers_up_to_N(1,N,Un), !.
  427.      list_of_natural_numbers_up_to_N(N1,N2,[N1|Un]) :-
  428.     N1 < N2, 
  429.     NN is N1 + 1, !, 
  430.     list_of_natural_numbers_up_to_N(NN,N2,Un).
  431.      list_of_natural_numbers_up_to_N(N1,N1,[N1]) :- !.
  432.      list_of_natural_numbers_up_to_N(_,_,[]).
  433.  
  434. %%% Succeeds if the input ground clause is a tautology.
  435.      tautology_clause(C) :-
  436.     append(_,[X|T],C),
  437.     negate(X,Y),
  438.     member(Y,T), !.
  439.  
  440. %%% Succeeds if the input first-order clause is a tautology.
  441.      fol_tautology_clause(C) :-
  442.     append(_,[X|T],C),
  443.     negate(X,Y),
  444.     identical_member(Y,T), !.
  445.  
  446. %%% return 1 if unit, otherwise 0.
  447.      decide_unit([_],1) :- !.
  448.      decide_unit(_,0) :- !.
  449.  
  450. %%% Assert X once.
  451.      assert_once(X) :-
  452.          X, !.
  453.      assert_once(X) :-
  454.       assert(X), !.
  455.  
  456. %%% Negate all literals in a clause.
  457.      negate_clause([D1|Ds1],[D2|Ds2]) :-
  458.     negate(D1,D2),
  459.     !, negate_clause(Ds1,Ds2).
  460.      negate_clause([],[]).
  461.  
  462. %%% List_vars generates a list of variables in a term.
  463.      list_vars(T,Vs) :- 
  464.     list_vars_1(T,[],Vs1),
  465.         identical_delete_all_duplicates(Vs1,Vs),
  466.     !.
  467.      list_vars_1(T,Vs,[T|Vs]) :-
  468.     var(T),
  469.     !.
  470.      list_vars_1(T,Vs1,Vs2) :-
  471.     functor(T,_,N),
  472.     list_vars_2(T,Vs1,Vs2,N).
  473.      list_vars_2(_,Vs,Vs,0).
  474.      list_vars_2(T,Vs1,Vs2,N) :-
  475.     arg(N,T,A),
  476.     list_vars_1(A,Vs1,Vs3),
  477.     N1 is N-1,
  478.     !,
  479.     list_vars_2(T,Vs3,Vs2,N1).
  480.  
  481. %%% Count_occurrences counts the number of times one term occurs in another.
  482.      count_occurrences(T1,T2,N) :- count_occurrences_1(T1,T2,0,N).
  483.      count_occurrences_1(T1,T2,N1,N2) :-
  484.     T1==T2,
  485.     !,
  486.     N2 is N1+1.
  487.      count_occurrences_1(T1,T2,N1,N2) :-
  488.     nonvar(T2),
  489.     !,
  490.     functor(T2,_,A),
  491.     count_occurrences_2(T1,T2,N1,N2,A).
  492.      count_occurrences_1(_,_,N,N).
  493.      count_occurrences_2(_,_,N,N,0).
  494.      count_occurrences_2(T1,T2,N1,N2,A) :-
  495.     arg(A,T2,T3),
  496.     count_occurrences_1(T1,T3,N1,N3),
  497.     A1 is A-1,
  498.     !,
  499.     count_occurrences_2(T1,T2,N3,N2,A1).
  500.  
  501. %%% Ground grounds a term.  Ground also returns a list of the variables in the
  502. %%% term and a list of the constants used to ground the term.
  503.      ground(T1,T2,Vs,Cs) :-
  504.     vars_tail(T1,Vs),
  505.         const_list(Cs),
  506.     not(not(ground1(T1,Vs))),
  507.     retract(grnd(T2)),
  508.     !.
  509.      ground1(T,Vs) :-
  510.     const_list(Vs),
  511.     asserta(grnd(T)),
  512.     !.
  513.  
  514. %%% Ground_like grounds a term using a specified list of variables and
  515. %%% constants.
  516.      ground_like(T1,T2,Vs,Cs) :-
  517.     not(not(ground_like1(T1,Vs,Cs))),
  518.     retract(grnd_like(T2)),
  519.     !.
  520.      ground_like1(T,Vs,Vs) :-
  521.     asserta(grnd_like(T)),
  522.     !.
  523.  
  524. %%% Unground ungrounds a grounded term.
  525.      unground(T,T,Vs,_) :-
  526.     var(Vs),
  527.     !.
  528.      unground(T1,T2,Vs,Cs) :-
  529.     atom(T1),
  530.     !,
  531.     unground1(T1,T2,Vs,Cs).
  532.      unground(T1,T2,Vs,Cs) :-
  533.     functor(T1,F,N),
  534.     unground2(T1,As,Vs,Cs,N,1),
  535.     T2=..[F|As].
  536.      unground1(T,T,Vs,_) :-
  537.     var(Vs),
  538.     !.
  539.      unground1(C,V,[V|_],[C|_]) :- !.
  540.      unground1(T1,T2,[_|Vs],[_|Cs]) :-
  541.     !,
  542.     unground1(T1,T2,Vs,Cs).
  543.      unground2(_,[],_,_,N,M) :-
  544.     M>N, 
  545.     !.
  546.      unground2(T,[A|As],Vs,Cs,N,M) :-
  547.     arg(M,T,A1),
  548.     unground(A1,A,Vs,Cs),
  549.     M1 is M+1,
  550.     !,
  551.     unground2(T,As,Vs,Cs,N,M1).
  552.  
  553. %%% Increment increments a counter.
  554.      increment_counter(C,N) :-
  555.     retract(counter(C,N1)),
  556.     N2 is N1+N,
  557.     assert(counter(C,N2)),
  558.     !.
  559.  
  560. %%% Set_counter sets a counter.
  561.      set_counter(C,N) :-
  562.     retract(counter(C,_)),
  563.     !,
  564.     assert(counter(C,N)),
  565.     !.
  566.      set_counter(C,N) :-
  567.     assert(counter(C,N)),
  568.     !.
  569.  
  570. %%% Logically erase a clause.
  571.      logically_erase(Proc,Ref) :-
  572.     assertz(logically_erased(Proc,Ref)).
  573.  
  574. %%% Physically erase the logically erased clauses of a procedure.
  575.      physically_erase(Proc) :-
  576.     retract(logically_erased(Proc,Ref)),
  577.     erase(Ref),
  578.     fail.
  579.      physically_erase(_).
  580.  
  581. %%% Obtain the Nth element of a list.
  582.      get_list(Xs,N,X) :- get_list(Xs,N,X,1).
  583.      get_list([X|_],N,X,N) :- !.
  584.      get_list([_|Xs],N,X,N1) :-
  585.     N2 is N1 + 1,
  586.     !,
  587.     get_list(Xs,N,X,N2).
  588.  
  589. %%% Get all distinct subterms of a term.
  590.      get_subterms(T,Ss) :-
  591.     get_subterms_1(T,Ss1),
  592.     identical_delete_all_duplicates(Ss1,Ss),
  593.     !.
  594.      get_subterms_1(T,[T]) :-
  595.     var(T),
  596.     !.
  597.      get_subterms_1(T,[T|Ss]) :-
  598.     functor(T,_,N),
  599.     get_subterms_2(T,N,Ss),
  600.     !.
  601.      get_subterms_2(_,0,[]).
  602.      get_subterms_2(T,N,Ss) :-
  603.     arg(N,T,T1),
  604.     get_subterms_1(T1,Ss1),
  605.     N1 is N-1,
  606.     get_subterms_2(T,N1,Ss2),
  607.     append(Ss2,Ss1,Ss),
  608.     !.
  609.  
  610. %%% Gensym -- from Clocksin and Mellish
  611.      gensym(Root,Atom) :-
  612.     get_num(Root,Num),
  613.     name(Root,Name1),
  614.     name(Num,Name2),
  615.     append(Name1,Name2,Name),
  616.     name(Atom,Name).
  617.      get_num(Root,Num) :-
  618.     retract(current_num(Root,Num1)),
  619.     !,
  620.     Num is Num1+1,
  621.     asserta(current_num(Root,Num)).
  622.      get_num(Root,1) :-
  623.     asserta(current_num(Root,1)).
  624.  
  625. %%% Common_variables determines the variables common to two terms.
  626.      common_variables(T1,T2,Vs) :-
  627.     list_vars(T1,Vs1),
  628.     list_vars(T2,Vs2),
  629.     common_variables_1(Vs1,Vs2,Vs).
  630.      common_variables_1([],_,[]).
  631.      common_variables_1([V|Vs1],Vs2,[V|Vs3]) :-
  632.     identical_member(V,Vs2),
  633.     !,
  634.     common_variables_1(Vs1,Vs2,Vs3).
  635.      common_variables_1([_|Vs1],Vs2,Vs3) :-
  636.     !,
  637.     common_variables_1(Vs1,Vs2,Vs3).
  638.  
  639. %%% Determine if one term S is a subterm of another term T.
  640.      is_subterm(S,T) :-
  641.     S==T,
  642.     !.
  643.      is_subterm(S,T) :-
  644.         nonvar(T),
  645.     !,
  646.     functor(T,_,N),
  647.     is_subterm_1(S,T,N).
  648.      is_subterm_1(_,_,0) :-
  649.     !,
  650.     fail.
  651.      is_subterm_1(S,T,N) :-
  652.     arg(N,T,T1),
  653.     is_subterm(S,T1),
  654.         !.
  655.      is_subterm_1(S,T,N) :-
  656.         N1 is N-1,
  657.     !,
  658.     is_subterm_1(S,T,N1).
  659.  
  660. %%% Determine if the first set is a subset of the second set.
  661.      identical_subset([],_).
  662.      identical_subset([A|X],Y) :-
  663.     identical_member(A,Y),
  664.         identical_subset(X,Y).
  665.  
  666. %%% Compute set difference.
  667.      identical_set_difference([],_,[]).
  668.      identical_set_difference([A|X],Y,Z) :-
  669.     identical_member(A,Y),
  670.     !,
  671.     identical_set_difference(X,Y,Z).
  672.      identical_set_difference([A|X],Y,[A|Z]) :-
  673.     identical_set_difference(X,Y,Z).
  674.  
  675. %%% substitute_term(T,U,V,Ts) :-
  676. %%%   input
  677. %%%     T  : term
  678. %%%     U  : term
  679. %%%     V  : term not identical to U
  680. %%%   output
  681. %%%     Ts : list of terms T' such T' is T with a single occurrence of U
  682. %%%          replaced by V.  Note that the length of Ts is equal to the number
  683. %%%          of occurrences of U in T.
  684.      substitute_term(T,U,V,Ts) :-
  685.     bagof1(T1,substitute_term_1(T,U,V,T1),Ts).
  686.      substitute_term_1(T1,U,V,T2) :-
  687.     substitute_term_2(T1,U,V,T2),
  688.     T1\==T2.
  689.      substitute_term_2(T,U,V,V) :-
  690.     T==U.
  691.      substitute_term_2(T,_,_,T) :-
  692.     var(T).
  693.      substitute_term_2(T1,U,V,T2) :-
  694.     nonvar(T1),
  695.     T1=..[F|Ts1],
  696.     substitute_term_3(Ts1,U,V,Ts2),
  697.     T2=..[F|Ts2].
  698.      substitute_term_3([],_,_,[]).
  699.      substitute_term_3([T1|Ts1],U,V,[T2|Ts2]) :-
  700.     substitute_term_2(T1,U,V,T2),
  701.         substitute_term_4(T1,T2,Ts1,U,V,Ts2).
  702.      substitute_term_4(T1,T2,Ts,_,_,Ts) :-
  703.     T1\==T2.
  704.      substitute_term_4(T1,T2,Ts1,U,V,Ts2) :-
  705.     T1==T2,
  706.     substitute_term_3(Ts1,U,V,Ts2).
  707.  
  708. %%% substitute_term_all(T1,U,V,T2) :-
  709. %%%   input
  710. %%%     T1 : term
  711. %%%     U  : term
  712. %%%     V  : term not identical to U
  713. %%%   output
  714. %%%     T2 : T with a all occurrences of U replaced by V.
  715.      substitute_term_all(T,U,V,V) :-
  716.     T==U,
  717.     !.
  718.      substitute_term_all(T,_,_,T) :-
  719.     var(T),
  720.         !.
  721.      substitute_term_all(T1,U,V,T2) :-
  722.     T1=..[F|Ts1],
  723.     substitute_term_all_1(Ts1,U,V,Ts2),
  724.     T2=..[F|Ts2].
  725.      substitute_term_all_1([],_,_,[]).
  726.      substitute_term_all_1([T1|Ts1],U,V,[T2|Ts2]) :-
  727.     substitute_term_all(T1,U,V,T2),
  728.         substitute_term_all_1(Ts1,U,V,Ts2).
  729.  
  730. %%% identical_embedded(U,V)
  731. %%%   input
  732. %%%     U : term
  733. %%%     V : term
  734. %%%   exception
  735. %%%     fails if U not embedded in V
  736.      identical_embedded(U,V) :-
  737.     U==V,
  738.     !.
  739.      identical_embedded(U,V) :-
  740.         var(V),
  741.     !,
  742.     fail.
  743.      identical_embedded(U,V) :-
  744.     nonvar(U),
  745.     functor(U,F,N),
  746.     functor(V,F,N),
  747.     U=..[_|Us],
  748.     V=..[_|Vs],
  749.     identical_embedded_1(Us,Vs).
  750.      identical_embedded(U,V) :-
  751.     V=..[_|Vs],
  752.     identical_embedded_2(U,Vs).
  753.      identical_embedded_1([],[]) :- !.
  754.      identical_embedded_1([U|Us],[V|Vs]) :-
  755.     identical_embedded(U,V),
  756.     identical_embedded_1(Us,Vs).
  757.      identical_embedded_2(U,[V|_]) :-
  758.     identical_embedded(U,V),
  759.     !.
  760.      identical_embedded_2(U,[_|Vs]) :-
  761.     identical_embedded_2(U,Vs).
  762.  
  763. %%% identical_set(S1,S2)
  764. %%%   input
  765. %%%     S1 : set
  766. %%%     S2 : set
  767. %%%   exceptions
  768. %%%     fails if S1 does not equal S2
  769.      identical_set(S1,S2) :-
  770.     length(S1,N),
  771.     length(S2,N),
  772.         identical_subset(S1,S2).
  773.  
  774. %%% replace_list(L1,N,T,L2)
  775. %%%   input
  776. %%%     L1 : list
  777. %%%     N  : integer
  778. %%%     T  : term
  779. %%%   output
  780. %%%     L2 : L1 with Nth element replaced with T
  781. %%%   exceptions
  782. %%%     fails if N<0 or N>|L|
  783.      replace_list(L1,N,T,L2) :- replace_list_1(L1,N,T,L2,1).
  784.      replace_list_1([_|L1],N,T,[T|L1],N) :- !.
  785.      replace_list_1([T1|L1],N,T2,[T1|L2],N1) :-
  786.     N2 is N1 + 1,
  787.     replace_list_1(L1,N,T2,L2,N2).
  788.  
  789. %%%
  790. %%% or_list(L,V)
  791. %%%   input
  792. %%%     L : list of 0s and 1s
  793. %%%   output
  794. %%%     V : or the elements of L where 0 is false and 1 is true
  795. %%%
  796.      or_list(L,1) :-
  797.     member(1,L),
  798.     !.
  799.      or_list(_,0).
  800.  
  801. %%%
  802. %%% permutations(L,P)
  803. %%%   input
  804. %%%     L : list
  805. %%%   output
  806. %%%     P : list of permutations of L
  807. %%%
  808.      permutations([],[[]]) :- !.
  809.      permutations([X],[[X]]) :- !.
  810.      permutations([X,Y],[[X,Y],[Y,X]]) :- !.
  811.      permutations(L,P) :-
  812.     bagof(Pi,permutations_1(L,Pi),Pis),
  813.     append_lists(Pis,P).
  814.      permutations_1(L,Pi) :-
  815.     member_N(L,X,L1),
  816.     permutations(L1,Pi1),
  817.     permutations_2(Pi1,X,Pi).
  818.      permutations_2([],_,[]) :- !.
  819.      permutations_2([L|Pi1],X,[[X|L]|Pi2]) :-
  820.        permutations_2(Pi1,X,Pi2).
  821.  
  822. %%%
  823. %%% append_lists(Ls,L)
  824. %%%   input
  825. %%%     Ls : list of lists
  826. %%%   output
  827. %%%     L  : lists of Ls appended together
  828. %%%
  829.       append_lists([],[]) :- !.
  830.       append_lists([L1|Ls],L2) :-
  831.     append_lists(Ls,L3),
  832.     append(L1,L3,L2).
  833.  
  834. %%%
  835. %%% tail(L,X)
  836. %%%   input
  837. %%%     L : list
  838. %%%   output
  839. %%%     X : last element in L
  840. %%%   exceptions
  841. %%%     fails if L is empty
  842. %%%
  843.      tail([X],X) :- !.
  844.      tail([_|L],X) :-
  845.        tail(L,X).
  846.  
  847. %%%
  848. %%% retract_all(X)
  849. %%%   input
  850. %%%     X : Prolog term
  851. %%%
  852.      retract_all(X) :-
  853.        retract(X),
  854.        fail.
  855.      retract_all(_).
  856.  
  857. %%%
  858. %%% term_size_structure(Term,Size_structure)
  859. %%%   input
  860. %%%     Term : Prolog term
  861. %%%   output
  862. %%%     Structure: term structured like Term containing subterm sizes.  For
  863. %%%                example, term_size_structure(f(f(X,g(a)),a),Structure) sets
  864. %%%                structure to ss(6,ss(4,ss(1),ss(2,ss(1))),ss(1)).
  865. %%%
  866.      term_size_structure(Term,ss(1)) :-
  867.     var(Term),
  868.         !.
  869.      term_size_structure(Term,Size_structure) :-
  870.     functor(Term,_,N),
  871.     term_size_structure_1(N,Term,0,Size1,Size_structure_list),
  872.     Size is Size1+1,
  873.     Size_structure =.. [ss,Size|Size_structure_list].
  874.      term_size_structure_1(0,_,Size,Size,[]) :- !.
  875.      term_size_structure_1(N,Term,Size1,Size2,
  876.       [Size_structure|Size_structure_list]) :-
  877.     functor(Term,_,M),
  878.     I is M-N+1,
  879.     arg(I,Term,Arg),
  880.     term_size_structure(Arg,Size_structure),
  881.         arg(1,Size_structure,Size3),
  882.     Size4 is Size1+Size3,
  883.     N1 is N-1,
  884.     term_size_structure_1(N1,Term,Size4,Size2,Size_structure_list).
  885.  
  886. %%%
  887. %%% enumerate(M,N,S,I)
  888. %%%   input
  889. %%%     M : integer
  890. %%%     N : integer
  891. %%%     S : non-zero integer
  892. %%%  output
  893. %%%     I : integer
  894. %%%  note:
  895. %%%    returns integers M through N inclusive by S via backtraking
  896. %%%
  897.      enumerate(M,N,S,_) :-
  898.        ((S>0, M>N);(S<0,M<N)),
  899.        !,
  900.        fail.
  901.      enumerate(M,N,_,M).
  902.      enumerate(M,N,S,I) :-
  903.        M1 is M+S,
  904.        enumerate(M1,N,S,I).
  905.